/**
 * CopyRight © 2012 USTC SINOVATE SOFTWARE CO.LTD All Rights Reserved.
 */

package com.cmcc.zysoft.infocollection.controller;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import jxl.Sheet;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cmcc.zysoft.framework.utils.StringUtil;
import com.cmcc.zysoft.framework.utils.UploadUtil;
import com.cmcc.zysoft.infocollection.common.BaseController;
import com.cmcc.zysoft.infocollection.constant.URLConstant;
import com.cmcc.zysoft.infocollection.mobile.service.MIndustryService;
import com.cmcc.zysoft.infocollection.mobile.service.MResourcePropertyService;
import com.cmcc.zysoft.infocollection.mobile.service.MServiceItemService;
import com.cmcc.zysoft.infocollection.model.Industry;
import com.cmcc.zysoft.infocollection.model.Resource;
import com.cmcc.zysoft.infocollection.model.ServiceItem;
import com.cmcc.zysoft.infocollection.service.CompanyPcService;
import com.cmcc.zysoft.infocollection.service.DepartmentPcService;
import com.cmcc.zysoft.infocollection.service.EmployeeService;
import com.cmcc.zysoft.infocollection.service.HeadshipPcService;
import com.cmcc.zysoft.infocollection.service.ResourcePcService;
import com.cmcc.zysoft.infocollection.service.RolePcService;
import com.cmcc.zysoft.infocollection.service.UserRolePcService;
import com.cmcc.zysoft.spring.security.model.User;
import com.cmcc.zysoft.spring.security.util.SecurityContextUtil;
import com.cmcc.zysoft.sysmanage.service.SystemUserPCService;
import com.cmcc.zysoft.sysmanage.service.UserRoleService;

/**
 * @author 袁凤建
 * <br />邮箱: yuan.fengjian@ustcinfo.com
 * <br />描述: controller.java
 * <br />版本: 1.0.0
 * <br />日期: 2013-8-19 下午5:28:14
 * <br />CopyRight © 2012 USTC SINOVATE SOFTWARE CO.LTD All Rights Reserved.
 */

@Controller
@RequestMapping("/mobile/test")
public class controller extends BaseController {

	@Value("${upload.file.path}")
	private String path;
	
	@Value("${info.query.url.prefix}")
	private String infoQueryUrlPrefix;
	
	@javax.annotation.Resource
	private MIndustryService mIndustryService;
	
	@javax.annotation.Resource
	private MServiceItemService mServiceItemService;
	
	@javax.annotation.Resource
	private ResourcePcService resourcePcService;
	
	@javax.annotation.Resource
	private EmployeeService employeeService;
	
	@javax.annotation.Resource
	private DepartmentPcService departmentPcService;
	
	@javax.annotation.Resource
	private HeadshipPcService headshipPcService;
	
	@javax.annotation.Resource
	private SystemUserPCService systemUserPCService;
	
	@javax.annotation.Resource
	private UserRoleService userRoleService;
	
	@javax.annotation.Resource
	private CompanyPcService companyPcService;
	
	@javax.annotation.Resource
	private RolePcService rolePcService;
	
	@javax.annotation.Resource
	private UserRolePcService userRolePcService;
	
	/**
	 * 属性名称: mResourcePropertyService.
	 * 类       型: MResourcePropertyService.
	 */
	@javax.annotation.Resource
	private MResourcePropertyService mResourcePropertyService;
	
	public static final String URL = "http://60.247.57.197:8180/WebDataHandler/live_api.search?" +
			"pid=test&vt=1&pt=2&ip=221.179.197.61&m=15901429817&ua=NokiaN+95&q=%E8%82%AF%E5%BE%B7%E5%9F%BA" +
			"&ps=10&pn=1&lpi=10&lci=00&lti=1001";
	
	/**
	 * 测试商户搜索.
	 * @return Document
	 * @throws Exception
	 * @测试地址:localhost:8080/mobile/test/example.htm
	 */
	@RequestMapping("/example.htm")
	@ResponseBody
	public Document example() throws Exception {
		Date date1 = new Date();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(URL);
        Element element = document.getDocumentElement();
        NodeList bookNodes = element.getElementsByTagName("result");
        for(int i = 0; i < bookNodes.getLength(); i++) {
        	NodeList childNodes = bookNodes.item(i).getChildNodes();
        	Node newChild = document.createElement("expired");
        	bookNodes.item(i).appendChild(newChild);
        	childNodes = this.nodeList(childNodes);
        }
        
        Date date2 = new Date();
        System.out.println("======================================================================================");
        System.out.println(date2.getTime() - date1.getTime());
        System.out.println("======================================================================================");
        return document;
	}
	
	/**
	 * 
	 * @param childNodes
	 * @return NodeList
	 * @throws Exception
	 */
	private NodeList nodeList(NodeList childNodes) throws Exception {
		String nodeName = ""; //节点名称
		String nodeValue = ""; //节点值
		String tradeId = ""; //服务项目ID
		String updateDate = ""; //更新时间
		String expiredValue = "0"; //expired节点的值
		Boolean isBlank = false; //必填字段是否为空
		Boolean isExpired = false; //是否过期
		//遍历单条记录,取出服务项目ID和更新时间
		for(int i = 0; i < childNodes.getLength(); i++) {
			Node node = childNodes.item(i);
			switch (node.getNodeName()) {
				case "trade_id"   : tradeId = node.getTextContent();  break;
				case "updated_at" : updateDate = node.getTextContent(); break;
				default           : break;
			}
		}
		//判断服务项目ID是否存在
		if(this.mServiceItemService.isServiceItemExist(tradeId)) { //服务项目ID存在
			ServiceItem serviceItem = this.mServiceItemService.getEntity(tradeId);
			Industry industry = serviceItem.getIndustry();
			Map<String, Object> map = this.mResourcePropertyService.getProperty(industry.getIndustryId());
			//遍历单条记录,判断是否存在必填字段为空
			for(int i = 0; i < childNodes.getLength(); i++) {
				nodeName = childNodes.item(i).getNodeName();
				nodeValue = childNodes.item(i).getTextContent();
				//判断是否存在必填字段为空
				isBlank = this.mServiceItemService.isNodeBlank(map, nodeName, nodeValue);
				if(isBlank) {
					expiredValue = "1"; //存在空值-数据缺失
					break;
				}
			}
		}
		//不存在必填字段为空时,判断是否过期
		if("0".equals(expiredValue)) {
			isExpired = this.mServiceItemService.isExpired(tradeId, updateDate);
			if(isExpired) {
				expiredValue = "2";
			} else {
				expiredValue = "0";
			}
		}
		for(int i = 0; i < childNodes.getLength(); i++) {
			if("expired".equals(childNodes.item(i).getNodeName())) {
				childNodes.item(i).setTextContent(expiredValue);
			}
		}
		System.out.println();
		return childNodes;
	}
	
	/**
	 * 测试搜索商户信息.
	 */
	@RequestMapping("/query.htm")
	@ResponseBody
	@Transactional
	public void query() {
		String infoId = "";
		String response = "";
		String dataSource = URLConstant.DATA_SOURCE;
		List<Resource> resourceList = this.resourcePcService.getResourceList();
		System.out.println("================================================================================");
		System.out.println("总数  : " +  resourceList.size());
		System.out.println("================================================================================");
		if(null != resourceList && !resourceList.isEmpty()) {
			Resource resource = null;
			for(int i = 0; i < resourceList.size(); i++) {
				resource = resourceList.get(i);
				System.out.println("resourceId : " + resource.getResourceId());
				infoId = resource.getState();
				response = this.getQueryResult(infoId, dataSource);
				this.queryJob(resource, response);
				System.out.println("response   : " + response);
			}
		}
	}
	
	/**
	 * 解析中央库返回报文并持久化至数据库.
	 * @param resource 商户信息
	 * @param response 中央库响应报文
	 */
	@Transactional
	public void queryJob(Resource resource, String response) {
		String shopId = ""; //商户ID
		String state = ""; //入库状态(1-入库等待,2-入库中,3-入库完成,4-入库失败)
		if(StringUtils.hasText(response)) {
			JSONObject object = JSONObject.parseObject(response);
			if("1".equals(object.get("status").toString())) {
				JSONArray object2 = object.getJSONArray("result");
				//判断中央库中商户是否删除
				if("{}".equals(object2.getJSONObject(0).toString())) { //中央库中商户已删除,更新本地入库状态为:入库失败(state=4)
					resource.setState("4");
				} else { //中央库商户未删除,更新中央库的入库信息至本地库
					for(int i = 0; i < object2.size(); i++) {
						JSONObject config = object2.getJSONObject(i);
						shopId = config.getString("id");
			        	state = config.getString("state");
					}
					resource.setState(state);
					resource.setShopId(shopId);
				}
				System.out.println("================================================================================");
	        	System.out.println("resourceId     : " + resource.getResourceId());
	        	System.out.println("流水号infoId   : " + resource.getInfoId());
	        	System.out.println("入库状态state  : " + resource.getState());
	        	System.out.println("================================================================================");
				//数据持久化至数据库
				this.resourcePcService.updateEntity(resource);
			}
		}
	}
	
	/**
	 * 获取查询结果.
	 * @param infoId 流水号ID
	 * @param dataSource 数据来源
	 * @return String
	 */
	private String getQueryResult(String infoId, String dataSource) {
		String response = "";
		try {
			String url = infoQueryUrlPrefix;
			String parameters =  StringUtil.formatMsg(URLConstant.INFO_QUERY_URL_PARAMETER, infoId, dataSource);
			//处理参数中的空格(" "),解决505错误问题(使用%20替换空格)
			parameters = parameters.replaceAll(" ", "%20");
			URL postUrl = new URL(url);
			HttpURLConnection connection = (HttpURLConnection) postUrl.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setInstanceFollowRedirects(false);
			connection.setRequestMethod("POST");
			connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			connection.setRequestProperty("charset", "UTF-8");
			connection.setRequestProperty("Content-Length", "" + Integer.toString(parameters.getBytes().length));
			connection.setUseCaches(false);
			DataOutputStream out = new DataOutputStream(connection.getOutputStream());
			out.writeBytes(parameters);
			out.flush();
			out.close();
			BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
	        String line = "";
	        while ((line = reader.readLine()) != null) {
	        	response = line;
	        }
	        reader.close();
	        connection.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return response;
	}
	
	/**
	 * 测试导入页面.
	 * @return String
	 */
	@RequestMapping("/import.htm")
	public String importEmp() {
		return "/pc/test/import";
	}
	
	/**
	 * 测试导入的实现方法.
	 * @param importExcel 选择的excel文件
	 * @return String
	 */
	@RequestMapping("/importAction.htm")
	@ResponseBody
	public String importUser(@RequestParam("importExcel") MultipartFile importExcel) {
		User user = SecurityContextUtil.getCurrentUser();
		String fileName = importExcel.getOriginalFilename();
		String saveName = System.currentTimeMillis() + UploadUtil.getExtention(fileName);
		//检查目录是否存在
		File filePath = new File(path);
		if(!filePath.exists()) {
			filePath.mkdirs();
		}
		//设置目录写权限
		filePath.setWritable(true);
    	String fileFullPath = path + File.separator + saveName;
    	File uploadfile = new File(fileFullPath);
    	try {
			FileCopyUtils.copy(importExcel.getBytes(), uploadfile);
			Workbook excel = Workbook.getWorkbook(uploadfile);
			Sheet sheet = excel.getSheet(0);
			String checkResult = this.employeeService.checkDataValidity(excel);
			if(StringUtils.hasText(checkResult)) {
				generateExcel(uploadfile, employeeService);
				return "C:\\备份文件已生成，请查看";
			} else {
				int rows = sheet.getRows();
				String companyName = ""; //公司名称
				String departmentName = ""; //部门名称
				String headshipName = ""; //岗位名称
				String userName = ""; //用户姓名
				String mobile = ""; //用户手机号码
				String currentUserId = "";
				for(int r = 1; r < rows; r++) {
					companyName = sheet.getCell(1, r).getContents().trim();
					departmentName = sheet.getCell(2, r).getContents().trim();
					headshipName = sheet.getCell(3, r).getContents().trim();
					userName = sheet.getCell(4, r).getContents().trim();
					mobile = sheet.getCell(5, r).getContents().trim();
					//检查企业是否存在
					String companyId = this.companyPcService.getCompanyId(null, companyName);
					//企业不存在时添加企业
					if(!StringUtils.hasText(companyId)) {
						companyId = this.companyPcService.addCompany(user.getUserId(), companyName);
					}
					//检查部门是否存在
					String departmentId = this.departmentPcService.getDepartmentId(companyId, null, departmentName);
					//部门不存在时添加部门
					if(!StringUtils.hasText(departmentId)) {
						departmentId = this.departmentPcService.addDepartment(companyId, user.getUserId(), departmentName);
					}
					//检查岗位是否存在
					String headshipId = this.headshipPcService.getHeadshipId(companyId, headshipName);
					//岗位不存在时添加岗位
					if(!StringUtils.hasText(headshipId)) {
						headshipId = this.headshipPcService.addHeadship(user.getUserId(), companyId, headshipName);
					}
					//添加员工
					String employeeId = this.employeeService.addEmployee(departmentId, headshipId, userName, mobile);
					//添加员工成功后添加用户
					if(StringUtils.hasText(employeeId)) {
						String userId = this.systemUserPCService.addSystemUser(currentUserId, companyId, headshipId, employeeId, userName, mobile);
						//检查角色是否存在
						String roleId = this.rolePcService.getCollectorRoleId();
						//角色不存在时添加角色
						if(!StringUtils.hasText(roleId)) {
							roleId = this.rolePcService.addRole(companyId);
						}
						//添加用户与角色的关联关系.
						this.userRolePcService.addUserRole(userId, roleId);
					}
				}
			}
			return "导入成功!";
		} catch (Exception e) {
			e.printStackTrace();
			return "报表导入失败,请稍候重试!";
		}
	}
	
	/**
	 * 生成新的Excel文件.
	 * @param file excel文件
	 * @param employeeService employeeService
	 * @throws Exception
	 */
	private static void generateExcel(File file, EmployeeService employeeService) throws Exception {
		Workbook workbook = Workbook.getWorkbook(file);
		WritableWorkbook writableWorkbook = Workbook.createWorkbook(new File("C:\\备份.xls"), workbook);
		WritableSheet sheet = writableWorkbook.getSheet(0);
		
		WritableFont font = new WritableFont(WritableFont.ARIAL, 12,
			     WritableFont.NO_BOLD, false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
		WritableCellFormat wcf = new WritableCellFormat(font); //单元格定义
		wcf.setBackground(Colour.YELLOW);
		wcf.setAlignment(Alignment.CENTRE);
		int rows = sheet.getRows();
		String companyName = ""; //公司名称
		String departmentName = ""; //部门名称
		String headshipName =  ""; //岗位名称 
		String userName = ""; //用户姓名
		String mobile = ""; //用户手机号码
		for(int r = 1; r < rows; r++) {
			companyName = sheet.getCell(1, r).getContents().trim();
			departmentName = sheet.getCell(2, r).getContents().trim();
			headshipName = sheet.getCell(3, r).getContents().trim();
			userName = sheet.getCell(4, r).getContents().trim();
			mobile = sheet.getCell(5, r).getContents().trim();
			if(!StringUtils.hasText(companyName)) {
				sheet.addCell(generateLabel(1, r, companyName, wcf));
			}
			if(!StringUtils.hasText(departmentName)) {
				sheet.addCell(generateLabel(2, r, departmentName, wcf));
			}
			if(!StringUtils.hasText(headshipName)) {
				sheet.addCell(generateLabel(3, r, headshipName, wcf));
			}
			if(!StringUtils.hasText(userName)) {
				sheet.addCell(generateLabel(4, r, userName, wcf));
			}
			if("".equals(mobile) || mobile.length() < 11 || mobile.length() > 11) {
				sheet.addCell(generateLabel(5, r, mobile, wcf));
			} else {
				if(employeeService.isPhoneNumexist(mobile, "0")) {
					sheet.addCell(generateLabel(5, r, mobile, wcf));
				}
			}
		}
		writableWorkbook.write();
		writableWorkbook.close();
	}
	
	/**
	 * 生成指定格式的单元格.
	 * @param row 行数
	 * @param col 列数
	 * @param content 单元格内容
	 * @param wcf WritableCellFormat
	 * @return Label
	 */
	private static Label generateLabel(int row, int col, String content, WritableCellFormat wcf) {
		return new Label(row, col, content, wcf);
	}
}